<template>
  <!-- 搜索 -->
  <div class="search">
    根据名字搜索：
    <el-select
      @clear="clearSearchKey"
      v-model="searchKey"
      filterable
      remote
      clearble
      placeholder="Please enter a keyword"
      :remote-method="remoteMethod"
      @change="searchChange"
      :loading="searchLoading"
    >
      <el-option
        v-for="item in searchOptions"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      />
    </el-select>
  </div>
  <!-- 添加按钮 -->
  <el-button type="primary" @click="addStu">+&nbsp;添加项目</el-button>
  <el-button  @click="exportExcel">
    <template #icon>
      <svg>
        <use class="icon" xlink:href="#icon-excel"></use>
      </svg>
    </template>
    <template #default>导出Excel</template>
  </el-button>
  <!-- 展示数据的表格 -->
  <div class="table">
    <el-table
      :data="tableData"
      v-loading="tableLoading"
      border
      style="width: 100%"
    >
      <el-table-column prop="headimgurl" label="头像" align="center">
        <template v-slot="{ row }">
          <el-avatar
            size="large"
            shape="square"
            :src="row.headimgurl"
          ></el-avatar>
        </template>
      </el-table-column>
      <el-table-column prop="name" label="名字" align="center" />
      <el-table-column prop="degree" label="学历" align="center" />
      <el-table-column prop="class" label="班级" align="center" />
      <el-table-column prop="productUrl" label="项目" align="center" />
      <el-table-column prop="cTime" label="创建时间" align="center" />
      <el-table-column prop="address" label="操作" align="center">
        <template v-slot="{ row }">
          <el-button type="success" :icon="View" circle />
          <el-button type="primary" :icon="Edit" @click="edit(row)" circle />
          <el-button type="danger" :icon="Delete" @click="del(row)" circle />
        </template>
      </el-table-column>
    </el-table>
  </div>
  <!-- 分页 -->
  <div>
    <el-pagination
      :page-size="pageSize"
      @current-change="pageChange"
      background
      layout="prev, pager, next"
      :total="total"
      :current-page="currentPage"
    />
  </div>
  <!-- 引入dialog弹窗组件 -->
  <qf-dialog
   
    :dialogFormData="dialogFormData"
    :visible="dialogVisible"
    :title="dialogTitle"
    @closed="close"
    @dialogCancel="dialogCancel"
    @validateSuccess="dialogFormValidateSuccess"
  >
    <template v-slot:upload>
      <el-upload
        class="avatar-uploader"
        v-loading="uploadLoading"
        method="post"
        action="/api/students/uploadStuAvatar"
        :show-file-list="false"
        name="headimgurl"
        :on-success="handleAvatarSuccess"
        :before-upload="beforeAvatarUpload"
      >
        <img v-if="imageUrl" :src="imageUrl" class="avatar" />
        <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
      </el-upload>
    </template>
  </qf-dialog>
</template>
<script setup>
//引入dialog弹窗组件
import qfDialog from "@/components/dialog/index.vue";
import { ref, reactive } from "vue";
import { ElMessage,ElMessageBox } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
//引入请求数据的方法
import * as api from "@/api/stu";
//引入图标
import { Delete, View, Edit } from "@element-plus/icons-vue";
import { onMounted } from "vue";
import qee from 'qf-export-excel'

//搜索逻辑
//搜索关键字
let searchKey = ref("");
//搜索的数据
let searchOptions = ref([]);
//搜索的加载动画
let searchLoading = ref(false);
//搜索框输入之后会会触发的方法,这里负责呈现搜索的联想数据
let remoteMethod = async (currentKeyword) => {
  if (!currentKeyword) {
    return;
  }
  searchLoading.value = true;
  // 三元表达式的目的是为了保证用户在输入或者选择的时候都能获取搜索到关键字
  // let key = searchKey.value?searchKey.value:currentKeyword
  try {
    //要搜索全部的数据，所以传递空字符count，默认走索全部
    let res = await api.searchStuListApi(currentKeyword, "");
    //给联想的列表赋值
    let repeatDatas = res.data.data.map((item) => ({ value: item.name }));
    //要去重操作
    let norepeatDatas = [];
    for (var i = 0; i < repeatDatas.length; i++) {
      //声明一个开关
      let flag = true;
      for (var j = 0; j < norepeatDatas.length; j++) {
        if (repeatDatas[i].value === norepeatDatas[j].value) {
          flag = false;
          break;
        }
      }
      if (flag) {
        norepeatDatas.unshift(repeatDatas[i]);
      }
    }
    //  console.log(repeatDatas)
    //  console.log(norepeatDatas)
    //去重之后给options进行赋值操作
    searchOptions.value = norepeatDatas;
    searchLoading.value = false;
  } catch (e) {
    console.log(e);
    searchLoading.value = false;
  }
};
//清空关键字之后的方法
let clearSearchKey = () => {
  //初始化数据，让页码重新回到第一页
  currentPage.value = 1;
};

//用户选择了输入框的值之后，负责更新表格数据
let searchChange = async (key, page = 1, count = 10) => {
  //获取用户点选的值
  //打开表格的loading动画
  tableLoading.value = true;
  //清空上次搜索到的选项
  searchOptions.value = [];
  try {
    let res = await api.searchStuListApi(searchKey.value, count, page);
    //对表格数据的操作，将搜索的结果赋值给表格
    tableData.value = res.data.data;
    tableLoading.value = false;
    //对搜索结果进行分页
    setPageNation(res.data.total);
  } catch (e) {
    tableLoading.value = false;
  }
};

//表格逻辑
//表格数据
let tableData = ref([]);
//加载动画
let tableLoading = ref(true);

//封装一个方法，专门用于获取表格数据
let getStulist = async (page, count, classes) => {
  //开启加载动画
  tableLoading.value = true;
  try {
    //请求列表数据
    let res = await api.getStuListApi(page, count, classes);
    // console.log(res);
    // 给表格数据赋值
    tableData.value = res.data.data;
    //关闭加载动画
    tableLoading.value = false;
    //设置分页器的数量
    setPageNation(res.data.total);
  } catch (e) {
    console.log(e);
    tableLoading.value = false;
  }
};
//处理分页器
//分页器的total属性
let total = ref(1);
//一页展示多少条
let pageSize = ref(10);
//默认的页码
let currentPage = ref(1);
//页码变更的时候
let pageChange = (inputCurrentPage) => {
  //动态变更页码
  currentPage.value = inputCurrentPage;
  //判断有没有搜索关键字，如果有那么应该更新搜索的分页结果
  if (searchKey.value) {
    searchChange(null, inputCurrentPage);
  } else {
    //页面切换，重新拉取列表
    getStulist(inputCurrentPage);
  }
};

//专门修改分页器内容的方法
let setPageNation = (totalCount = 10, count = 10, currentPage = 1) => {
  total.value = totalCount;
  pageSize.value = count;
};

//添加stu信息
//声明dialogVisible控制dialog
//dialog标题
let dialogTitle = ref("增加数据");
let dialogVisible = ref(false);
let addStu = () => {
  //打开dialog
  dialogVisible.value = true;
  dialogTitle.value = "增加数据";
};
//dialog的数据源
let dialogFormData = reactive({
  class: {
    label: "班级",
    value: "",
  },
  name: {
    label: "姓名",
    value: "",
  },
  age: {
    label: "年龄",
    value: "",
  },
  city: {
    label: "城市",
    value: "",
  },
  degree: {
    label: "学历",
    value: "",
  },
  productUrl: {
    label: "项目地址",
    value: "",
  },
  description: {
    label: "描述",
    value: "",
  },
});

//dialog点击了确定按钮，并且表单校验通过触发的逻辑
let dialogFormValidateSuccess = async (form) => {
  //发起请求，将输入的内容传递给服务器
  // console.log(dialogFormData);
  let message = "添加成功";
  //传递给后台的数据
  let params = {
    headimgurl: "",
    class: dialogFormData.class.value,
    name: dialogFormData.name.value,
    age: dialogFormData.age.value,
    city: dialogFormData.city.value,
    degree: dialogFormData.degree.value,
    productUrl: dialogFormData.productUrl.value,
    description: dialogFormData.description.value,
  };
  try {
    let apiMethod = null;
    switch (dialogTitle.value) {
      case "增加数据":
        apiMethod = api.addStuApi;
        //删除sId这条数据
        params.sId ? delete params.sId : "";
        break;
      case "编辑数据":
        apiMethod = api.updateStuApi;
        //给params中添加sId属性
        params.sId = sId.value;
        //更改提示信息
        message = "修改成功";
    }
    //判断是否上传头像，如果上传了，那么携带到params中去
    params.headimgurl = headimgurl.value ? headimgurl.value : "";

    // console.log(apiMethod);
    let res = await apiMethod(params);
    console.log(res);
    //根据dialogTitle来区分要发送编辑请求还是发送增加请求
    //添加成功
    //1.提示添加成功
    ElMessage({
      type: "success",
      message,
    });
    //2.关掉dialog
    dialogVisible.value = false;
    //3.清空表单
    form.value.resetFields();
    //4.更新列表
    getStulist();
    console.log(res);
  } catch (e) {
    // console.log(e)
    ElMessage({
      type: "error",
      message: e.toString(),
    });
  }
};

//点击dialog取消按钮触发的逻辑
let dialogCancel = () => {
  dialogVisible.value = false;
  console.log("已经取消");
};

//dialog关闭之后，要同步控制关闭属性的值
//这么做的目的 是为了处理点击空白或者右上角叉叉的时候，造成的后续dialog不能弹出的情况
let close = () => {
  dialogVisible.value = false;
  let keys = Object.keys(dialogFormData);
  keys.forEach((key) => {
    dialogFormData[key].value = "";
  });
  //清空头像的回显
  imageUrl.value = "";
};

//编辑
//声明一个变量，储存sId，便于编辑的时候传递给后端
let sId = ref("");
let edit = (row) => {
  console.log(row);
  //1.打开dialog
  dialogVisible.value = true;
  //2.修改标题
  dialogTitle.value = "编辑数据";
  //3.数据需要回显
  let keys = Object.keys(dialogFormData);
  keys.forEach((key) => {
    dialogFormData[key].value = row[key];
  });
  //给sId赋值
  sId.value = row.sId;
  //更改全局的 headimgurl这个字段，便于数据的传递
  headimgurl.value = row.headimgurl;
  //回显
  (imageUrl.value = row), headimgurl;
};

//删除
let del = (row) => {
  //获取当前这条数据的id，传递给后台
  //1.先交互，让用户确认是否删除
  ElMessageBox.confirm('此操作将永久删除这条数据 '+row.name+'，是否继续？','删除提示',
  {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
   .then(async ()=>{
     //2.发请求，删除数据
     try{
          let res = await api.delStuApi(row.sId)
          ElMessage({
            type:'success',
            message:'删除成功'
          })
          //更新列表
          getStulist()
     }catch(e){
          ElMessage({
            type:'error',
            message:e.toString()
          })
     }
   })
   .catch(()=>{
    ElMessage({
      type:'warning',
      message:'已取消删除'
    })
   })
};

//导出Excel
let exportExcel = ()=>{
  //定义表头
  let titleSource = [
    {
      title:'姓名',
      key:'name'
    },
    {
      title:'年龄',
      key:'age'
    },
    {
      title:'头像地址',
      key:'headimgurl'
    },
    {
      title:'学历',
      key:'degree'
    },
    {
      title:'班级',
      key:'class'
    },
  ]
    qee(titleSource,tableData.value,'工资单')
}

//上传文件
//声明一个保存上传地址的变量
let imageUrl = ref();
//声明一个headimgurl变量，用于将参数在表单dialog通过的时候，一并提交给后台
let headimgurl = ref("");
//加载动画
let uploadLoading = ref(false);
//上传成功的方法
let handleAvatarSuccess = (res, uploadFile) => {
  if (res.state) {
    //头像上传成功
    ElMessage({
      type: "success",
      message: res.msg,
    });
    headimgurl.value = res.headimgurl;

    //加载动画
    uploadLoading.value = false;
  } else {
    ElMessage({
      type: "error",
      message: res.msg,
    });
  }
  // console.log(res)
  // console.log(uploadFile.raw)
  //加载动画
  uploadLoading.value = false;
  imageUrl.value = URL.createObjectURL(uploadFile.raw);
};

//上传之前
let beforeAvatarUpload = (rawFile) => {
  //允许上传的文件类型
  let acceptType = ["image/jpeg", "image/png"];
  //判断当前上传的文件类型是否包含在上面的数组中
  let isAccept = acceptType.includes(rawFile.type);
  if (!isAccept) {
    ElMessage.error(
      "上传的文件类型只能是jpeg或者png,您当前上传的文件类型是" + rawFile.type
    );
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("上传的文件不能超过1M");
    return false;
  }
  //打开加载动画
  uploadLoading.value = true;
  return true;
};
onMounted(() => {
  getStulist();
});
</script>
<script>
export default {
  meta: {
    title: "xyxmgl",
    name: "学员项目管理",
    routeName: "stuProduct",
    icon: "icon-shangpinguanli",
  },
};
</script>
<style scoped>
.search {
  margin: 40px 0;
}
/* .el-button{
  width: 100px;
  height: 30px;
  margin-bottom: 40px;
} */
.el-pagination {
  margin-left: 35%;
  margin-top: 20px;
}
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>
